home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / rtnews.zip / RTNEWS2 < prev    next >
Text File  |  1992-09-13  |  77KB  |  1,748 lines

  1.  
  2.  _ __                 ______                         _ __
  3. ' )  )                  /                           ' )  )
  4.  /--' __.  __  ,     --/ __  __.  _. o ____  _,      /  / _  , , , _
  5. /  \_(_/|_/ (_/_    (_/ / (_(_/|_(__<_/ / <_(_)_    /  (_</_(_(_/_/_)_
  6.              /                               /|
  7.             '                               |/
  8.  
  9. Ray Tracing News, e-mail edition, 2/15/88
  10.  
  11. concatenated by Eric Haines, hpfcla!hpfcrs!eye!erich@hplabs.HP.COM
  12.  
  13. So, now that the SIGGRAPH paper submission rush is over, the SIGGRAPH paper
  14. review process begins.  Fortunately, it's generally easier to comment on someone
  15. else's deathless prose than write it yourself.  It's also time to start
  16. procrastinating on writing up SIGGRAPH tutorial notes.  So, all in all it's
  17. not been too busy, except for all the "real" work we've all (hopefully) been
  18. doing.
  19.  
  20.  
  21. Dore'
  22. -----
  23.  
  24. The only new news I've got is on the new product by Ardent, called Dore'
  25. (rhymes with "moray" - there should be an up-accent over that "e" in Dore).
  26. Ardent is the new name for Dana Computer Inc (i.e. the "single-user
  27. supercomputer/supergraphics" people.  Their "Titan" minisupercomputer is due
  28. out realsoonnow).  Dore' stands for "Dynamic Object-Rendering Environment".
  29.  
  30. The places I've seen articles so far is "Electronics", February 4, 1988, on
  31. pages 69-70, and "Mini-Micro Systems", February 1988, pages 22-23.  The
  32. first article offers more detail.  I don't really want to rehash either
  33. article in full.  The salient points (to me) about Dore' are:
  34.  
  35.     (1) Toolkit approach.
  36.     (2) Can render using vectors, hidden surface, or ray tracing.
  37.     (3) Hierarchical, object oriented system.
  38.     (4) Five object classes:
  39.         (a) primitives (including points, curves, polygons, meshes, cubic
  40.         solids (?!), and NURBS (non-uniform rational B-splines),
  41.         (b) appearance attributes (material properties, inc. solid texture
  42.         maps and environmental reflection maps),
  43.         (c) geometric attributes (modeling matrices),
  44.         (d) studio objects (camera, lights) (I like this term!),
  45.         (e) organizational objects (hierarchy, and evidentally the ability
  46.         to define function calls inside the environment which call
  47.         routines in the application program.  No idea how this works).
  48.     (5) Quoted times: 0.1 second for vector, 10 seconds for hidden
  49.         surface, 100 seconds ray-traced (I assume on the Titan.  No
  50.         idea what kind of scene complexity or resolution).
  51.     (6) Written in C.
  52.     (7) "Open" system - source code sold in hopes of selling Dore' on other
  53.         systems.
  54.  
  55. The best part (for universities and research labs) is the price: $250 for
  56. a source code license - not sure what the cost is for source code maintenance
  57. (vs. $15000 for commercial users plus $5000/year after the first year).  Per
  58. copy binary license is $200.
  59.  
  60. I am teaching the ray-tracing section of "A Consumer's and Developer's Guide
  61. to Image Synthesis" at SIGGRAPH this year, so definitely want to know more.
  62. I would also like more information just out of curiosity.  So, you university
  63. people, please go out there and get one - seems like a real bargain.  The
  64. contact info for Ardent is:
  65.  
  66.     Ardent Computer Corp
  67.     550 Del Rey Ave
  68.     Sunnyvale, CA  94086
  69.     408-732-2806
  70.  
  71.  
  72. That's all, folks,
  73.  
  74. Eric
  75.  
  76.    
  77.  
  78.  _ __                 ______                         _ __
  79. ' )  )                  /                           ' )  )
  80.  /--' __.  __  ,     --/ __  __.  _. o ____  _,      /  / _  , , , _
  81. /  \_(_/|_/ (_/_    (_/ / (_(_/|_(__<_/ / <_(_)_    /  (_</_(_(_/_/_)_
  82.              /                               /|
  83.             '                               |/
  84.  
  85.             "Light Makes Right"
  86.  
  87.              March 1, 1988
  88.  
  89.  
  90. I just receive Andrew's note that the hardcopy RTN is in the mail, which
  91. inspired me to flush the buffer and send on the latest offerings.  Special
  92. thanks to Jeff Goldsmith for submissions.
  93.  
  94.     - Eric
  95.  
  96. --------------------------------------------------
  97.  
  98. Mailing list updates
  99. --------------------
  100.  
  101. First, an address change.  John Peterson is now with Apple, who writes:
  102.  
  103.     'I'm currently hanging out at Apple thinking about "3D graphics for the
  104.     rest of us" and how to keep the jaggies away from personal computers.
  105.     (But there is this Cray sitting about 50 feet away.  Hmmm...)'
  106.  
  107. #
  108. # John Peterson - bicubic splines, texturing
  109. # Apple Computer (graduated University of Utah, 1988)
  110. alias    john_peterson    hpfcrs!hpfcla!jp%apple.apple.com@RELAY.CS.NET
  111.  
  112. I asked him for ray tracers at the University of Utah.  So, Tom Malley and
  113. Rod Bogart (whose initials are 'RGB') are now subscribers.
  114.  
  115. From Tom:
  116.     My thesis research was similar to what John Wallace described,
  117.     being a two pass approach to radiosity to include specular reflection
  118.     and transparency.  Form factors were all calculated via ray tracing,
  119.     however.  I did some brief examination of different ray intersection
  120.     methods along the way (Rubin-Whitted, Kay-Kajiya, and Glassner).
  121.  
  122. #
  123. # Tom Malley - blending ray tracing and radiosity
  124. # Evans & Sutherland (graduated University of Utah, 1988)
  125. # (malley@cs.utah.edu, cs.utah.edu!esunix!tmalley)
  126. alias    tom_malley    hpfcrs!hpfcla!hplabs!malley@cs.utah.edu
  127.  
  128.  
  129. To quote John Peterson about Rod Bogart:
  130.     Rod developed a really neat method for using ray tracing to integrate
  131.     computer generated pictures with real world images (coming soon to a
  132.     SIGGRAPH near you...).
  133.  
  134. #
  135. # Rod Bogart - blending ray tracing and images
  136. # University of Utah
  137. alias    rod_bogart    hpfcrs!hpfcla!hplabs!bogart%gr@cs.utah.edu
  138.  
  139. -----------------------------------
  140.  
  141. Another Dore' Article
  142.  
  143. In case you have not been able to track down the two articles previously
  144. mentioned about Dore', Ardent's new rendering system, there's now a third
  145. (that I know of):  it's in "Computer Design", Feb 15, 1988, pages 30-31.
  146. Pretty much like the other articles (i.e. cast from the same press release).
  147.  
  148. -----------------------------------
  149.  
  150. Responses to the "teapot in a football stadium" problem:
  151.  
  152.  
  153. From: Andrew Glassner
  154.  
  155.  Just a quick response to your football stadium/teapot example.  When you
  156. subdivide a node, look at its children.  If only one child is non-empty,
  157. replace the original node with its non-null child.  Do this recursively 
  158. until the subdivision criterion is satisfied.  I do this in my spacetime
  159. ray tracer, and the results can be big.  The ray propagation can get just
  160. a bit more complex, but there are clever rays to keep it simple (see
  161. John Amanatide's article in Eurographics '87, plus I have a scheme that
  162. I hope to write up soon...).
  163.  
  164.   Better yet, go with a hybrid space subdivision/bounding volume scheme,
  165. such as the one described in my spacetime paper (poorly described in the
  166. Intro to RT notes, but better described in the version slated for the
  167. March issue of CG&A; I'd be happy to mail you a preprint).  I think this
  168. hybrid scheme gives the best of both worlds, and you can use whatever
  169. space subdivision and bounding volume techniques that you like in the
  170. two distinct phases of the algorithm.  I use adaptive space subdivision
  171. and Kay's bounding slabs, and that combination seems to work pretty well.
  172.  
  173.   And now I have to get back to moving into my office!
  174.  
  175. ------------------------------------------
  176.  
  177. Comments on Jim Arvo's Efficiency Article
  178.  
  179.  
  180. From: Eric Haines (with a few extra comments than my original letter to Jim)
  181.  
  182.     Your article on efficiency is fascinating.  I hope to read it more
  183. carefully tonight and (eventually--we just came under a crunch of work)
  184. comment on it.  Sounds like you've done a lot of serious thought and
  185. speculation on the possibilities.  I agree with the philosophy of objects
  186. each having their own private hierarchies, and having the ability to hook
  187. these hierarchies up however you want.  We've done that on a small scale
  188. with our tesselated spline surfaces:  automatic hierarchy a la Goldsmith &
  189. Salmon (IEEE CG&A, May 1987) for everything, but then octrees for the spline
  190. surfaces themselves.  A nice feature of Goldsmith is that you can weight the
  191. cost of each primitive into the algorithm: multiply its area by some
  192. intersection cost (which you'll probably have to figure out through
  193. experimentation) to give it a weighting.  In this way a torus surface which has
  194. the same size bounding volume as a quadrilateral can be given a higher
  195. weighting factor.  A higher cost has the effect of making the hierarchical tree
  196. less horizontal near the complicated object, i.e. there are more bounding
  197. volumes overall, with a few complicated objects in each.  This is what you
  198. want, since you'd rather spend a little extra time on intersecting bounding
  199. volumes than wasting a lot of time intersecting the empty space around costly
  200. objects.
  201.  
  202.  
  203. Response from: Jim Arvo
  204.  
  205.     I'm glad you found my article interesting.  All your interesting
  206.     mail finally motivated me to contribute to the discussion.  I
  207.     thought I would toss out a pet idea of mine and see if it sparked
  208.     any debate.  It turns out that Jeff Goldsmith also looked at
  209.     simulated annealing for bounding box hierarchies.  One day one 
  210.     of us will get some results.  Hopefully not negative results!
  211.  
  212.     With all the talk about octrees and such, it's clear that there 
  213.     are a number of potential papers "waiting in the wings".  I've
  214.     been thinking that by getting the right collaborations going,
  215.     we (the ray tracing group) could easily "hand" IEEE several
  216.     related papers, effectively defining a theme issue.  What do
  217.     you think?
  218.  
  219.  
  220. My reply:
  221.  
  222.     The efficiency article collection sounds possible.  Another idea which
  223. someone (Mike Kaplan, maybe?  I forget) mentioned at last SIGGRAPH was "A
  224. Characterization of Ten Ray Tracing Efficiency Algorithms".  If well done, this
  225. would be a classic.  There are probably entirely new schemes still to be found,
  226. and certainly trying to optimize and figure out good hybrid methods is an
  227. area ripe for development.  But right now many of the structures and algorithms
  228. are in place, and still have not been fully compared.  Timings are
  229. unconvincing, and statistics are worthwhile but don't tell the whole story.
  230. An in-depth comparison of the major algorithms and techniques to improve these
  231. would be wonderful.  Someday, someday ... well, my hope is that a few of us
  232. could do some writing along these lines, even if it's just brainstorming on
  233. how to compare particular algorithms in a rigorous fashion  (e.g. How can we
  234. simulate a scene mathematically?  OK, idealize each object as a box or sphere
  235. for simplicity.  Now, how do we distribute the points to get realistic
  236. clustering? Once we have a "scene generator" which could create various typical
  237. distributions of objects in a scene, then we have to analyze how this generator
  238. would interact with each algorithm, and be able to predict how each efficiency
  239. scheme deals with the scenes generated.  Or there might be simpler ways to
  240. isolate and analyze each factor which affects the efficiency of a scheme.
  241. Anyway, whatever, but this stuff looks fun!).  Understanding the strengths of
  242. the various techniques seems vital to being able to do any kind of "annealing"
  243. process for optimization.
  244.  
  245. ------------------------------------------------------------
  246.  
  247. Efficiency Tricks
  248. -----------------
  249.  
  250. From Jeff Goldsmith:
  251.  
  252.     Here's a good hack for Ray Tracing News:
  253. When using Tim Kay's heapsort on bounding volumes in order
  254. to get the closest, don't bother to do that for illumination
  255. rays.  I know it seems obvious, but I never thought to do it.
  256.  
  257. The obvious corollary to that idea has a little more reach to
  258. it.  Since illumination rays form the bulk of the rays we 
  259. trace, getting the nearest intersection is of limited value.
  260. In addition, if CSG is used, more times occur when the nearest
  261. intersection is of less value.  This seems to indicate that 
  262. space tracing techniques are doing some amount of needless work.
  263. Since it doesn't really cost that much, perhaps it is not a flaw,
  264. but maybe space tracers should consider approaches that don't
  265. worry about where along the path we are and optimize that problem
  266. instead.
  267.  
  268. ---------------------------------------------
  269.  
  270. More Book Recommendations
  271. -------------------------
  272.  
  273. From: Jeff Goldsmith
  274.  
  275.     I agree completely with your comment about libraries.
  276. Mine is a crucial resource for me.  Here are some of my
  277. favorite books that are in my office:
  278.  
  279.     Geometry:
  280.     
  281.         Computational Geometry for Design and Manufacture
  282.             Faux & Pratt
  283.          --an early CAD text.  It has lots of good stuff
  284.         on splines and 3D math.
  285.  
  286.         Differential Geometry of Curves and Surfaces
  287.         DoCarmo
  288.         --A super text on classical differential geometry.
  289.         (Not quite the same as analytic geometry.)
  290.  
  291.         CRC Standard Math Tables
  292.         --This has an awesome section on analytic geometry.
  293.         Calculus, too.  Can't live without it.  It is not
  294.         the same as the first part of the Chemistry and 
  295.         Physics one.
  296.  
  297.         Analytic Geometry
  298.         Steen and Ballou
  299.         --Once was the standard college text on the subject.
  300.         That was a long time ago, but it is very easy to
  301.         read and it covers the fundamentals.
  302.  
  303.     Computing:
  304.  
  305.         Data Structures and Algorithms
  306.         --Aho, Hopcroft and Ullman
  307.         Read anything by these guys.
  308.  
  309.         Data Structure Techniques
  310.         --Standish
  311.         More How-to than AHU's tome.
  312.  
  313.         Numerical Analysis
  314.         --Burden, Faires, and Reynolds
  315.         I have the other two, as well.  This is the
  316.         least complete of the three, but the algorithms
  317.         inside are childishly easy to implement.  They
  318.         always seem to work, too.  Best of all, for many
  319.         cases, they have test data and solutions.
  320.  
  321.         Software Tools
  322.         --Kernighan and Plauger
  323.         How to write command line interpreters, editors,
  324.         macro expanders, the works.  Great reading.
  325.  
  326.         Fundamentals of Computer Algorithms
  327.         --Horowitz and Sahni
  328.         Less technical than AHU, but pretty technical.
  329.         Thicker.  It may very well answer the problem
  330.         you can't figure out straight off.
  331.  
  332.         The Art of Computer Programming
  333.         --Knuth
  334.         The "Encyclopedia"
  335.  
  336.     Physics:  (Seem awfully useful sometimes)
  337.  
  338.         Gravitation
  339.         --Misner, Thorne, and Wheeler
  340.         The thickest book on my shelf.  It's a paperback, too.
  341.         (It's bent three bookends permanently.  Cheap JPL ones.)
  342.         Truly a tome on modern physics.
  343.         
  344.         Modern Physics
  345.         --Tippler
  346.         Much easier to read than MTW.  Has lots of good appendices.
  347.  
  348.         University Astronomy
  349.         --Pasachoff and Kuttner
  350.         I read this book for fun.  I wonder why I didn't read it
  351.         while I was taking Kuttner's course?
  352.  
  353.         The Feynman Lectures on Physics
  354.         Awesome first course.  Most of my needs are problems in
  355.         the text.
  356.  
  357.     Graphics, etc:
  358.  
  359.         Raster Graphics Handbook
  360.         --Conrac
  361.         All about fundamentals of the craft.
  362.  
  363.         Light and Color in Nature and Art
  364.         --Williamson and Cummings
  365.         Much easier to read than Hall's thesis, but less 
  366.         technical as well. 
  367.  
  368.     Etc, Etc:
  369.  
  370.         The Random House Dictionary of the English Language, 
  371.         College Edition
  372.         The best collegiate sized dictionary around. 
  373.         By far.
  374.  
  375.         The Chicago Manual of Style
  376.         Has most of the answers. Did you know that
  377.         to recreate is to have fun, but to 
  378.         re-create is computer graphics?
  379.  
  380.         The Elements of Style
  381.         The one that came before computers.
  382.  
  383. -----------------------------------------------
  384.  
  385. Bug for the Day                        by Eric Haines
  386. ---------------
  387.  
  388. {This will be pretty unexciting for those who never intend to implement an
  389. octree subdivision scheme.  For future implementers, I hope you find it of
  390. use:  it took me quite a few hours to track this one down, so I think it is
  391. worth going into.}
  392.  
  393.     This bug was one I had when implementing octree subdivision for ray
  394. tracing.  The basic algorithm used was Glassner's:  once you intersect the
  395. octree structure, move the intersection point in one half of the smallest
  396. cube's dimension in the direction normal to the wall hit.  In other words,
  397. find out what cube is the next cube by finding a point that should be well
  398. inside of it, then translating this point into integer octree coordinates
  399. and traversing the octree downwards until a leaf node is found.
  400.  
  401.     However, there are some subtle errors that can occur with moving to the
  402. next octree cube.  My favorite is almost hitting the edge of a cube, moving
  403. into the next cube, then getting caught moving to the cube diagonal to this
  404. cube, i.e. moving from cube 1 to 2 to 3 ...
  405.  
  406.     X-->
  407.     +---+---+
  408.       ^ | 2 | $ |    Numbers are the order of cubes moved through.
  409.       | +---#---+
  410.       Y | 1 | 3 |
  411.     +---+---+
  412.       ^________ray started here, and hit almost at the "#".
  413.            (ray is in +X, +Y direction)
  414.  
  415. This went into an infinite loop, going between 2 and 3 forever.  The reason
  416. was that when I hit the boundary 1&2 I would add a Y increment (half minimum
  417. box size) to the intersection point, then convert this to find that I was
  418. now in box 2.  I would then shoot the ray again and it would hit the
  419. wall at 2&$.  To this intersection point I would add an X increment.  However,
  420. what would happen is that the Y intersection point would actually be ever so
  421. slightly low - earlier when I hit the 1&2 wall adding the increment pushed us
  422. into box 2.  But now when the Y intersection point was converted it would
  423. put us in the 1+3 boxes, and X would then put us in box 3.  Basically, the
  424. precision of the machine made the mapping between world space and octree
  425. space be ever so slightly off.
  426.  
  427.     The infinite loop occurred when we shot the ray again at box 3.  It
  428. would hit the 3/$ wall, get Y incremented, and because X was ever so slightly
  429. less than what was truly needed to put the intersection point in the 3+$
  430. boxes, we would go back to box 2, ad infinitum.  Another way to look at this
  431. is that when we would intersect the ray against any of the walls near the
  432. "#" point, the intersection point (due to roundoff) was always mapping to
  433. box 1 if not incremented.  Incrementing in Y would move it to box 2, and in
  434. X would move it to box 3, but then the next intersection test would yield
  435. another point that would be in box 1.  Since we couldn't increment in
  436. both directions at once, we could never get past 2 and 3 simultaneously.
  437.  
  438.     This bug occurs very rarely because of this: the intersection points
  439. all have to be such that they are very near a corner, and the mapping of the
  440. points must all land within box 1.  This problem occurred for me once in a
  441. few million rays, which of course made it all that much more fun to search
  442. for it.
  443.  
  444.     My solution was to check the distance of the intersections generated
  445. each time: if the closest intersection was a smaller distance from the origin
  446. than the closest distance for the previous cube move, then this intersection
  447. point would not be used, but rather the next higher would be.  In this way
  448. forward progress along the ray would always be made.
  449.  
  450.     By the way, I found that it was worthwhile to always use the original
  451. ray origin for testing ray/cube intersections - doing this avoids any
  452. cumulative precision errors which could occur by successively starting from
  453. each new intersection point.  To simulate the origin starting within the cube
  454. I would simply test only the 3 cube faces which faced away from the ray
  455. direction (this was also faster to test).
  456.  
  457.     Anyway, hope this made sense - has anyone else run into this bug? Any
  458. other solutions?
  459.  
  460. ---------------------------------------------
  461.  
  462. A Pet Peeve (by Jeff Goldsmith)
  463. -----------
  464.  
  465. Don't ever refer to pixels as rows and columns.  It makes it
  466. hard to get the order (row,column)? (column,row)? right.  Refer
  467. to pixels as (x,y) coordinates.  Not only is that the natural
  468. system to do math on them, but it is much easier to visualize
  469. in a debugging environment, as well as running the thing.  I
  470. use the -x and -y npix switches on the tracer command line to
  471. override any settings and have found them to be much easier to
  472. deal with than the -r and -c that seem to be everywhere.  Note
  473. that C's normal array order is (I think.  I always get these 
  474. things wrong.) (y,x).
  475.  
  476.     [I agree: my problem now is that Y=0 is the bottom edge of the screen
  477.     when dealing with the graphics package (HP's Starbase), and Y=0 is the
  478.     top when directly accessing the frame buffer (HP's SRX). -- EAH]
  479.  
  480. ---------------------------------------------
  481.  
  482.     Next "RT News" issue I'll include a write-up of Goldsmith/Salmon which
  483. should hopefully make the algorithm clearer, plus some little additions I've
  484. made.  I've found Goldsmith/Salmon to be a worthwhile, robust efficiency scheme
  485. which hasn't received much attention.  It embodies an odd way of thinking
  486. (I have to reread my notes about it when I want to change the code), as there
  487. are a number of costs which must be taken into account and inherited.  It's
  488. not immediately intuitive, but has a certain sense to it once all the pieces
  489. are in place.  Hopefully I'll be able to shed some more light on it.
  490.  
  491. All for now,
  492.  
  493. Eric
  494.  
  495.  _ __                 ______                         _ __
  496. ' )  )                  /                           ' )  )
  497.  /--' __.  __  ,     --/ __  __.  _. o ____  _,      /  / _  , , , _
  498. /  \_(_/|_/ (_/_    (_/ / (_(_/|_(__<_/ / <_(_)_    /  (_</_(_(_/_/_)_
  499.              /                               /|
  500.             '                               |/
  501.  
  502.             "Light Makes Right"
  503.  
  504.              March 8, 1988
  505.  
  506. -------------------------------------------------
  507.  
  508. Surface Acne
  509. ------------
  510.  
  511. From Eric Haines:
  512.  
  513.     A problem which just about every ray tracer has run into, and which
  514. has rarely appeared in the literature (and even more rarely been solved in any
  515. way) is what I call "surface acne".
  516.  
  517.     An easy way to explain this problem is with an example.  Say you are
  518. looking at a double sided (i.e. no culling) cylinder primitive.  You shoot an
  519. eye ray, hitting the outside.  Now you look at a light.  As it turns out, the
  520. intersection point truly is bathed by the light, and so should see it.  What
  521. actually may happen is that the shadow test ray hits the cylinder.  In images
  522. this will show up as black dots or other anomalous shadings - "surface acne".
  523. I've seen this left in some images to give an interesting textured effect, but
  524. normally it's a real problem.
  525.  
  526.     How did this happen?  Well, theoretically it can't.  However, due to
  527. precision error the following happens.  When you hit the cylinder and
  528. calculated the intersection point in world space, the point computed was
  529. actually ever so slightly inside the cylinder.  Now, when the shadow ray
  530. is sent out, it is tested against the cylinder's surface, and an intersection
  531. is found at some tiny distance from the origin.
  532.  
  533.     A common solution is to just assign an epsilon to each intersector and
  534. cross your fingers.  In other words, what you really do is move the ray origin
  535. ever so slightly along the shadow (or reflection or refraction) ray direction
  536. and hope this was far enough that the new origin is 'outside' of the object
  537. (in actuality, what you want is for the new origin to be on the same side of
  538. the object as the parent ray, except for refraction rays, which want to start
  539. on the opposite side).  This works fairly well for test systems, but is pretty
  540. scary stuff for software used by anyone who didn't design it (e.g. some user
  541. decides to input his molecular database in meters, causing all his data to be
  542. much smaller in radius than my fudge factor.  When I add my fudge factor
  543. distance to the ray, I find that my new ray origin is way outside the scene).
  544.  
  545.     Another solution is to not test the item intersected if it is not
  546. self-shadowing.  For example, a polygon cannot cast a shadow on itself, so
  547. should not be tested for intersection when a ray originates on its surface.
  548. This works fine for some primitives, but falls apart when self-shadowing
  549. objects (cylinders, tori, spline surfaces, etc) are used.
  550.  
  551.     I have also experimented with some root polishing techniques, which
  552. help to solve some problems, but I'll leave it at this for now.  Has anyone
  553. any better solutions for surface acne (ideally foolproof ones)?  I suspect
  554. that the best solution is a combination of the above techniques, but hopefully
  555. I'm missing some concept that might make this problem easy to solve.  Hope to
  556. hear from you all on this!
  557.  
  558. -------------
  559.  
  560. Addenda from Jeff Goldsmith:
  561.  
  562.     Al [Barr] and I have used a technical term for "surface acne,"
  563. too.  We called it "black dots" or more often "black shit."
  564. (Zbuffers have similar problems.  The results are called
  565. "zbuffer shit" or "zippers".  Mostly the cruder term is
  566. used since the artifacts are not particularly desirable.)
  567.  
  568. --------------------------------------------------
  569.  
  570. Goldsmith/Salmon Hierarchy Building
  571. -----------------------------------
  572.  
  573. Well, I was going to write up some info on the Goldsmith/Salmon hierarchy
  574. building algorithm, but the RT News buffer was filled almost immediately and 
  575. I haven't done it yet.  However, there was this from Jeff Goldsmith, about
  576. his earlier paper (IEEE CG&A, May 1987):
  577.  
  578.        If you are going to spend some time and effort on automatic
  579.     tree generation stuff (Note: paper 2 is almost done--mostly
  580.     talks about parallelism and hypercubes, but some stuff on trees
  581.     as well--mostly work heuristics that include primitives
  582.     and so on) I'd like to hear some thinking about the evaluation
  583.     function.  Firstly, it's optimized for primary rays.  That turns
  584.     out to be an unfortunate choice, since most rays are secondary
  585.     rays.  We've come up with a second order correction that is 
  586.     good for evaluating trees, but turns the generation algorithm
  587.     into O(n log^2 n).  We've not played around with it enough to
  588.     tell whether it works.  If you have some thoughts/solutions,
  589.     that would be nice.  Another finding on the same vein that is
  590.     much more important is: the mean (see next note) seems to be 
  591.     reasonably close, but sigma is very high for the predictions
  592.     vs. actual tries.  This wasn't important (actually, wasn't
  593.     detected) on a sequential machine, but became crucial on a
  594.     parallel machine.  Some of the variation is due to our assumption/
  595.     attempt at view direction independence.  (Clearly, stuff in back
  596.     is not checked for intersection much.)  I don't know whether
  597.     that is all of it--we get bizarre plots of this data.  If you
  598.     have any thoughts on how to make a better or more precise
  599.     evaluation function, I'd really like to hear the reasoning and
  600.     perhaps steal and use the results.  
  601.     Oh, the promised note: The mean is only correct if the highest
  602.     level bounding volume (root node) is contained completely within
  603.     the view volume.  If it isn't, the actual results end up proportional
  604.     to the predicted ones, but I haven't worked out the constant.  
  605.     (It shows up on our graphs pretty clearly, though.)
  606.  
  607.     The second part of the algorithm is the builder.  I'm not
  608.     convinced that it is a very good method at all, but it met the
  609.     criteria I set up when trying to decompose trees--O(below n^2)
  610.     and reasonably local (I was trying to use simulated annealing
  611.     at the time.)  Some other features were environmental; some were
  612.     because I couldn't think of a better way.  In no sense am I convinced
  613.     that the incremental approach or the specific one chosen is best.
  614.     I'd like to hear about that, too.
  615.  
  616.     The only part I really like about the whole thing is the 
  617.     general approach of using heuristics to guess at some value
  618.     (rated in flops eventually) and then trying to optimize that
  619.     value.  Beyond that, I think there is a whole realm of computational
  620.     techniques waiting to be used to approximately solve optimization
  621.     problems.  I'm really interested in other work done in that 
  622.     direction and especially results regarding graphics.
  623.  
  624.     Thanks for the good words; I seem to have been mentioned
  625.     in most of the last issue.  I bet that has something to do with
  626.     my having acquired a network terminal on my desk less than a 
  627.     month ago (yay!).  
  628.  
  629. -----------------------------------------------------
  630.  
  631. Efficiency Tricks followup
  632. --------------------------
  633.  
  634. These are comments generated by Jeff Goldsmith's note that Kay/Kajiya sorting is
  635. not needed for shadow rays.
  636.  
  637. -----------
  638.  
  639. Comments from Masataka Ohta:
  640.  
  641. In the latest ray tracing news, you write:
  642.  
  643. >Efficiency Tricks
  644.  
  645. >Since illumination rays form the bulk of the rays we 
  646. >trace.
  647.  
  648. If so, instead of space tracing, you should use ray coherence
  649. at least for the illumination rays.
  650.  
  651. The ray coherent approaches are found in CG&A vol. 6, no. 9 "The
  652. Light Buffer: A Shadow-Testing Accelerator" and in my paper "ray
  653. coherence theorem and constant time ray tracing algorithm" in
  654. proceedings of CG International '87.
  655.  
  656. >In addition, if CSG is used, more times occur when the nearest
  657. >intersection is of less value.  This seems to indicate that 
  658. >space tracing techniques are doing some amount of needless work.
  659.  
  660. How about tracing illumination rays from light sources, instead
  661. of from object surface? It will be faster for your CSG case,
  662. if the surface point lies in the shadow, though if the surface
  663. point is illuminated, there will be no speed improvement.
  664.  
  665. The problem is interesting to me because my research on coherent
  666. ray tracer also suggests that it is much better to trace illumination
  667. rays from the light source.
  668.  
  669. Do you have any other reasons to determine from where illumination rays
  670. are fired?
  671.  
  672. ----------------------------------------------------------------------
  673.  
  674. Jeff Goldsmith's reply:
  675.  
  676. Actually, I believe you, though I won't say with certainty 
  677. that we know the best way to do shadow testing.  However,
  678. I'm interested in fundamentally understanding the ray tracing
  679. algorithm and determining what computation MUST be done, so
  680. the realization that space tracing illumination rays still
  681. seems meaningful.  In fact, it is my opinion that space tracing
  682. is not the right way to go and "backwards" (classical) ray
  683. tracing will eventually be closer to what will be used 30
  684. years from now.  I won't even try to defend that position;
  685. no one knows the answers.  What we are trying to do is
  686. shed a little "light" on the subject.  Thanks for your
  687. comments.
  688.  
  689. -----------------
  690.  
  691. From Eric Haines:
  692.  
  693.     I just got from Ohta the same note Ohta sent to you, plus your reply.
  694. Your reply is so short that I've lost the sense of it.  So, if you don't mind,
  695. a quick explanation would be useful.
  696.  
  697. > However,
  698. > I'm interested in fundamentally understanding the ray tracing
  699. > algorithm and determining what computation MUST be done, so
  700. > the realization that space tracing illumination rays still
  701. > seems meaningful.
  702.  
  703. What is "the realization that space tracing illumination rays"?  I'm missing
  704. something here - which realization?
  705.  
  706. > In fact, it is my opinion that space tracing
  707. > is not the right way to go and "backwards" (classical) ray
  708. > tracing will eventually be closer to what will be used 30
  709. > years from now.
  710.  
  711. Do you mean by "space tracing" Ohta's method?
  712.  
  713. Basically, it looks like I should reread Ohta's article, but I thought I'd
  714. check first.
  715.  
  716. --------------
  717.  
  718. Further explanation from Jeff Goldsmith:
  719.  
  720. I think that a word got dropped from the sentence, either when I
  721. typed it in or later.  (Who knows--I do that about as often as
  722. computers do.)
  723.  
  724. I meant:  Since distance order is not needed for illumination
  725. rays, space tracing methods in general (not Ohta's in particular)
  726. do extra work.  It's not always clear that extra information costs
  727. extra computation, but they usually go hand in hand.  (It was just
  728. a rehash of the original message.)  Anyway, if extra computation is
  729. being done, perhaps then there is an algorithm that does not do 
  730. this computation, yet does all the others (or some others...)
  731. that is of lower asymptotic time complexity.  
  732.  
  733. Basically, this all boils down to my response to various claims
  734. that people have "constant time" ray tracers. It is just not 
  735. true.  It can't be true if they are using a method that will yield
  736. the first intersection along a path since we know that that 
  737. computation cannot be done in less than O(n log n) without a
  738. discretized distance measurement.  I don't think that space
  739. tracers discretize distance in the sense of a bucket sort, but
  740. I could be convinced, I suppose.  Anyway, that's what the ramblings
  741. are all about.  If you have some insights, I'd like to start an
  742. argument (sorry, discussion) on the net about the topic.  What
  743. do you think?
  744.  
  745. ------------------------------------------------------------
  746.  
  747. Extracts from USENET news
  748. -------------------------
  749.  
  750. There was recently some interesting interchange about octree building on USENET.
  751. Some people don't read or don't receive comp.graphics, so the rest of this
  752. issue consists of these messages.
  753.  
  754. ----------------
  755.  
  756. From Ruud Waij (who is not on the RT News e-mail mailing list):
  757.  
  758. In article <198@dutrun.UUCP> winffhp@dutrun.UUCP (ruud waij) writes:
  759. My ray tracing program, which can display the 
  760. primitives block, sphere cone and cylinder, 
  761. uses spatial enumeration of the object space 
  762. (subdivision in regularly located cubical cells 
  763. (voxels)) to speed up computation.
  764.  
  765. The voxels each have a list of primitives.
  766. If the surface of a primitive is inside a voxel,
  767. this primitive will be put in the list of the voxel.
  768.  
  769. I am currently using bounding boxes around the 
  770. primitives: if part of the bounding box is 
  771. inside the voxel, the surface of the primitive 
  772. is said to be inside the voxel.
  773. This is a very easy method but also very s-l-o-w.
  774.  
  775. I am trying to find a better way of determining 
  776. whether the surface of a primitive is in a voxel 
  777. or not, but I am not very succesful.
  778. Does anyone out there have any suggestions ?
  779.  
  780. ---------------
  781.  
  782. Response from Paul Heckbert:
  783.   
  784. Yes, interesting problem!  Fitting a bounding box around the object and listing
  785. that object in all voxels intersected by the bounding box will be inefficient as
  786. it can list the object in many voxels not intersected by the object itself.
  787. Imagine a long, thin cylinder at an angle to the voxel grid.
  788.  
  789. I've never implemented this, but I think it would solve your
  790. problem for general quadrics:
  791.  
  792.     find zmin and zmax for the object.
  793.     loop over z from zmin to zmax, stepping from grid plane to grid plane.
  794.     find the conic curve of the intersection of the quadric with the plane.
  795.     this will be a second degree equation in x and y (an ellipse,
  796.         parabola, hyperbola, or line).
  797.     note that you'll have to deal with the end caps of your cylinders
  798.         and similar details.
  799.     find ymin and ymax for the conic curve.
  800.     loop over y from ymin to ymax,
  801.         stepping from grid line to grid line within the current z-plane
  802.         find the intersection points of the current y line with the conic.
  803.         this will be zero, one, or two points.
  804.         find xmin and xmax of these points.
  805.         loop over x from xmin to xmax.
  806.         the voxel at (x, y, z) intersects the object
  807.  
  808. Perhaps others out there have actually implemented stuff like this and will
  809. enlighten us with their experience.
  810.  
  811. -----------------
  812.  
  813. Response from Andrew Glassner:
  814.  
  815.   Ruud and I have discussed this in person, but I thought I'd respond
  816. anyway - both to summarize our discussions and offer some comments
  817. on the technique.
  818.  
  819.   The central question of the posting was how to assign the surfaces
  820. of various objects to volume cells, in order to use some form spatial
  821. subdivision to accelerate ray tracing.  Notice that there are at
  822. least two assumptions underlying this method.  The first assumes that 
  823. the interior of each object is homogeneous in all respects, and thus
  824. uninteresting from a ray-tracing point of view.  As a counterexample,
  825. if we have smoke swirling around inside a crystal ball, then this
  826. "homogeneous-contents" assumption breaks down fast.  
  827.  
  828.   To compensate, we either must include the volume inside each object 
  829. to each cell's object list (and support a more complex object description
  830. encompassing both the surface and the contents), or include as new objects 
  831. the stuff within the original.  
  832.  
  833.   The other assumption is that objects have hard edges; otherwise we have 
  834. to revise our definition of "surface" in this context.  This can begin
  835. to be a problem with implicit surfaces, though I haven't seen this really
  836. discussed yet in print.  But so as long as we're using hard-edged objects 
  837. with homogeneous interiors, the "surface in a cell" approach is still 
  838. attractive.  From here on I'll assume that cells are rectangular boxes.
  839.  
  840.   So to which cells do we attach a particular surface?  Ruud's current 
  841. technique (gathered from his posting) finds the bounding box of the surface 
  842. and marks every cell that is even partly within the bounding volume.  Sure,
  843. this marks a lot of cells that need not be marked.  One way to reduce the
  844. marked cell count is to notice that if the object is convex, we can unmark 
  845. any cell that is completely within the object; we test the 8 corners with 
  846. an inside/outside test (fast and simple for quadrics; only slightly slower 
  847. and harder for polyhedra).  If all 8 corners are "inside", unmark the cell.  
  848. Of course, this assumes convex cells - like boxes.  Note that some quadrics
  849. are not convex (e.g. hyperboloid of one sheet) so you must be at least
  850. a little careful here.
  851.  
  852.   The opposite doesn't hold - just because all 8 corners are outside
  853. does NOT mean a cell may be unmarked.  Consider the end of a cylinder
  854. poking into one side of a box, like an ice-cream bar on a stick,
  855. where the ice-cream bar itself is our cell.  The stick is within the 
  856. ice cream, but all the corners of the ice cream bar are outside the stick.  
  857. Since this box contains some of the stick's surface, the box should still 
  858. be marked.  So our final cells have either some inside and some outside 
  859. corners, or all outside corners.
  860.  
  861.   What do we lose by having lots of extra cells marked?  Probably not
  862. much.  By storing the ray intersection parameter with each object after
  863. an intersection has been computed, we don't ever need to actually
  864. repeat an intersection.  If the ray id# that is being traced matches
  865. the ray id# for which the object holds the intersection parameter, we
  866. simply return the intersection value.  This requires getting access to
  867. the object's description and then a comparison - probably the object
  868. access is the most expensive step.  But most objects are locally
  869. coherent (if you hit a cell containing object A, the next time you need
  870. object A again will probably be pretty soon).  So "false positives" -
  871. cells who claim to contain an object they really don't - aren't so bad,
  872. since the pages containing an object will probably still be resident
  873. when we need it again.
  874.  
  875.   We do need to protect ourselves, though, against a little gotcha that
  876. I neglected to discuss in my '84 CG&A paper.  If you enter a cell and
  877. find that you hit an object it claims to contain, you must check that
  878. the intersection you computed actually resides within that cell.  It's
  879. possible that the cell is a false positive, so the object itself isn't
  880. even in the cell.  It's also possible that the object is something like
  881. a boomerang, where it really is within the current cell but the actual
  882. intersection is in another cell.  The loss comes in when the intersection
  883. is actually in the next cell, but another surface in the next cell (but
  884. not in this one) is actually in front.  Even worse, if you're doing CSG, 
  885. that phony intersection can distort your entire precious CSG status tree!
  886. The moral is not to be fooled just because you hit an object in a cell; 
  887. check to be sure that the intersection itself is also within the cell.  
  888.  
  889.   How to find the bounding box of a quadric?  A really simple way is
  890. to find the bounding box of the quadric in its canonical space, and
  891. then transform the box into the object's position.  Fit a new bounding
  892. box around the eight transformed corners of the original bounding box.
  893. This will not make a very tight volume at all, (imagine a slanted,
  894. tilted cylinder and its bounding box), but it's quick and dirty and 
  895. I use it for getting code debugged and at least running.
  896.  
  897.   If you have a convex hull program, you can compute the hull for
  898. concave polyhedra and use its bounding box; obviously you needn't
  899. bother for convex polyhedra.  For parametric curved surfaces you can
  900. try to find a polyhedral shell the is guaranteed to enclose the
  901. surface; again you can find the shell's convex hull and then find
  902. the extreme values along each co-ordinate.
  903.  
  904.   If your boxes don't have to be axis-aligned, then the problem changes
  905. significantly.  Consider a sphere: an infinite number of equally-sized
  906. boxes at different orientation will enclose the sphere minimally.  More
  907. complicated shapes appear more formidable.  An O(n^3) algorithm for
  908. non-aligned bounding boxes can be found in "Finding Minimal Enclosing
  909. Boxes" by O'Rourke (International Journal of Computer and Information
  910. Sciences, Vol 14, No 3, 1985, pp. 183-199).  
  911.  
  912.   Other approaches include traditional 3-d scan conversion, which I think
  913. should be easily convertable into an adaptive octree environment.  Or you
  914. can grab the bull by the horns and go for raw octree encoding, approximating
  915. the surface with lots of little sugar cubes.  Then mark any cell in your
  916. space subdivision tree that encloses (some or all of) any of these cubes.
  917.  
  918.  
  919.  
  920.  
  921.  _ __                 ______                         _ __
  922. ' )  )                  /                           ' )  )
  923.  /--' __.  __  ,     --/ __  __.  _. o ____  _,      /  / _  , , , _
  924. /  \_(_/|_/ (_/_    (_/ / (_(_/|_(__<_/ / <_(_)_    /  (_</_(_(_/_/_)_
  925.              /                               /|
  926.             '                               |/
  927.  
  928.             "Light Makes Right"
  929.  
  930.              March 26, 1988
  931.  
  932.  
  933.  
  934. Table of Contents:
  935.     Intro, Eric Haines
  936.     Mailing list changes and additions: Kuchkuda, Lorig, Rekola
  937.     More on shadow testing, efficiency, etc., Jeff Goldsmith
  938.     More comments on tight fitting octrees for quadrics, Jeff Goldsmith
  939.     LINEAR-TIME VOXEL WALKING FOR OCTREES, Jim Arvo
  940.     Efficiency Tricks, Eric Haines
  941.     A Rendering Trick and a Puzzle, Eric Haines
  942.     PECG correction, David Rogers
  943.  
  944. ---------------------------------------------------------------
  945.  
  946. Well, NCGA was pretty uninspiring, as it rapidly becomes more and more PC
  947. oriented. It was great to see people, though, and nice to escape the Ithaca
  948. snow and rain.
  949.  
  950. As far as ray tracing goes, a few companies announced products.  The AT&T
  951. Pixel Machine now has two rendering packages, PICLIB and RAYLIB (these may
  952. be merged into one package someday - I would guess that separate development
  953. efforts caused the split [any comments, Leonard?]).  With the addition of some
  954. sort of VM capability, this machine becomes pretty astounding in its ray
  955. tracing performance (in case you didn't get to SIGGRAPH last year, they had
  956. a demo of moving by mouse a shiny ball on top of the mandrill texture map:
  957. about a frame per second ray trace on a small part of the screen).  HP
  958. announced its new graphics accelerator, the TurboSRX, and with it the eventual
  959. availability of a ray tracing and (the first!) radiosity package as an extension
  960. to their Starbase graphics library.  Ardent and their Dore' package were sadly
  961. missing.  Apollo was also noticeable for their non-appearance.  Sun TAAC was
  962. there, showing off some ray traced pictures but seemingly not planning to
  963. release a ray tracer (the salesman claiming that whoever bought a TAAC would
  964. simply write their own).  Stellar was there with their supercomputer
  965. workstation - interesting, but no ray-tracing in sight.  Anyone else note
  966. anything of ray-tracing (or other) interest?
  967.  
  968. -------------------------------------------------------------------------
  969.  
  970. Some mailing list changes and additions
  971.  
  972. Changed address:
  973.  
  974. # Roman Kuchkuda
  975. # Megatek
  976. alias    roman_kuchkuda \
  977.     hpfcrs!hpfcla!hplabs!ucbvax!ucsd!megatek!kuchkuda@rutgers.edu
  978.  
  979.  
  980. New people:
  981.  
  982. I saw Gray at NCGA and got his email address.  He worked on ray tracing at
  983. RPI and is at Cray:
  984.  
  985. # Gray Lorig - volumetric data rendering, sci-vi, and parallel & vector
  986. #    architectures.
  987. # Cray Research, Inc.
  988. # 1333 Northland Drive
  989. # Mendota Heights, MN  55120
  990. # (612)-681-3645
  991. alias    gray_lorig    hpfcrs!hpfcla!hplabs!gray%rhea.CRAY.COM@uc.msc.umn.edu
  992.  
  993.  
  994. By way of introduction, this from Erik Jansen:
  995.  
  996.     I visited the Helsinki University of Technology last week and found 
  997.     there a lot of ray tracing activities going on. They are even reviving 
  998.     their old EXCELL system (Markku Tamminen did a PhD work on a spatial 
  999.     index based on an adaptive binary space subdivision in '81-'82, I met 
  1000.     him in '81 and '82 and we talked at these occasions about ray tracing 
  1001.     and spatial subdivision. In his PhD thesis (1982) there is a ray tracing 
  1002.     algorithm given for the EXCELL method (EXtendible CELL method).
  1003.     I decided to implement the algorithm for ray tracing polygon models.
  1004.     That implementation failed because I could only use our PDP-11 at that 
  1005.     time and I could have about ten cells in internal memory - too less
  1006.     for effective coherence. The program spend 95% of its time on swapping.
  1007.     So far the history).
  1008.     I told them about the RT-news and they are very interested to receive
  1009.     it. I will mail them (Charles Woodward, Panu Rekola, e.o.) your address,
  1010.     so that they can introduce themselves to the others.
  1011.  
  1012. #
  1013. # Panu Rekola - spline intersection, illumination models, textures
  1014. # Helsinki University of Technology
  1015. # Laboratory of Information Processing Science
  1016. # Room Y229A
  1017. # SF-02150 Espoo
  1018. # Finland
  1019. #    pre@kiuas.hut.fi    (or pre@hutcs.hut.fi)
  1020. alias    panu_rekola    hpfcrs!hpfcla!hpda!uunet!mcvax!hutcs!pre
  1021.  
  1022. Panu Rekola writes:
  1023.  
  1024.     I just received a message from Erik Jansen (Delft) in which he told
  1025.     me that you take care of a mailing list called "Ray Tracing News".
  1026.     (I already sent a message to Andrew Glassner on the same topic because
  1027.     Erik told me to contact him when he visited us some weeks ago.)
  1028.     Now, I would like to join the discussion; I promise to ask no stupid
  1029.     questions. I have previously worked here in a CAD project (where I wrote
  1030.     my MSc thesis on FEM elements) and since about a year I have been 
  1031.     responsible of our graphics. Even though my experience in the field is
  1032.     quite short I suppose I have learned a lot while all people want to see
  1033.     their models in color and with glass etc., visualization has been the
  1034.     bottleneck in our CAD projects.
  1035.  
  1036.     As an introduction to the critical members of the mailing list you
  1037.     could tell that I am a filter who read unstandard input from the models
  1038.     created by other people, manipulates the data with the normal graphics
  1039.     methods, and outpus images. The special features of our ray tracer are
  1040.     the EXCELL spatial directory (which has been optimized for ray tracing
  1041.     during the last few weeks), a new B-spline (and Bezier) algorithm,
  1042.     methods to display BR models with curved surfaces (even blend surfaces,
  1043.     although this part yet unfinished). The system will be semi-commercially
  1044.     used in a couple of companies soon (e.g. car and tableware industry).
  1045.  
  1046. ------------------------------------------------------------------------
  1047.  
  1048. More on shadow testing, efficiency, etc. (followup to Ohta/Goldsmith
  1049. correspondence):
  1050.  
  1051. From Jeff Goldsmith:
  1052.  
  1053.     Sorry I haven't responded sooner, but movie-making has taken
  1054.     up all my time recently.  
  1055.  
  1056.     With respect to pre-sorting, etc.  It is important to note
  1057.     that the preprocessing time must be MUCH smaller than the 
  1058.     typical rendering time.  So far this has been true, and 
  1059.     even more so for animation.
  1060.  
  1061.     O(n) in my writing (explicitly in print) means linear in the
  1062.     number of objects in the scene.  Obviously, it is quite likely
  1063.     that the asymptotic time complexity (a.t.c.) of any ray tracing algorithm
  1064.     will be different for the number of rays.  Excluding ray coherence
  1065.     methods and hybrid z-buffer/ray tracing methods, the current
  1066.     a.t.c. is O(n) in the number of rays for ray tracing.  Actually, I
  1067.     think it is the same for these other methods because the hybrid
  1068.     methods just eliminate some of the rays from consideration and
  1069.     leave the rest to be just as hard and the coherence methods don't
  1070.     eliminate more than, say, 1/2 of the rays, I think.  In any event,
  1071.     for the a.t.c. to become sub-linear, there can be no such fraction,
  1072.     right?
  1073.  
  1074.     About space tracing: I think that I said that finding the 
  1075.     closest intersection is an O(log n) problem.  I agree, though,
  1076.     that that statement is not completely correct.  Bucket sort
  1077.     methods, for example, can reduce the a.t.c. below log n.  Also,
  1078.     global sort time (preprocessing) can distribute some of the
  1079.     computation across all rays, which can reduce the time complexity.
  1080.     What about the subdivide on the fly methods?  (e.g:
  1081.     Arvo and Kirk)  How do they fit in the scheme of things?
  1082.     I think your evaluation of the space tracing methods is correct,
  1083.     though the space complexity becomes important here, too.  Also,
  1084.     given a "full" space (like Fujimoto's demos,) the time complexity
  1085.     is smaller.  That leads to the question, "What if the time complexity
  1086.     of an algorithm depends on its input data?" Standard procedure is
  1087.     to evaluate "worst case" complexity, but we are probably interested
  1088.     in "average case" or more likely, "typical case."  Also, it would
  1089.     be worthwhile and interesting to understand which algorithms do
  1090.     better with which type of data.  We need to quantify this answer
  1091.     when trying to find good hybrid schemes.  (The next generation?)
  1092.  
  1093.     At SIGGRAPH '87 we had a round table and each answered the question,
  1094.     "what would you like to see happen to ray tracing in the next year."
  1095.     My choice was to see something proven about ray tracing.  It sounds
  1096.     like you are interested in that too.  Any takers?
  1097.  
  1098. --------------------------------------------------------------------
  1099.  
  1100. More comments on tight fitting octrees for quadrics
  1101. {followup to Ruud Waij's question last issue}
  1102.  
  1103. From Jeff Goldsmith:
  1104.  
  1105.     With respect to the conversation about octree testing, I've only
  1106.     done one try at that.  I just tested 9 points against the implicit
  1107.     representation of the surface.  (8 corners and the middle.)  I didn't
  1108.     use it for ray tracing (I even forget what for) but I suspect that 
  1109.     antialiasing will hide most errors generated that way.
  1110.  
  1111.     Jim Blinn came up with a clever way to do edges and minima/
  1112.     maxima of quadric surfaces using (surprise) homogeneous coordinates.
  1113.     I don't think there ever was a real paper out of it, but he published
  1114.     a tutorial paper in the Siggraph '84 tutorial notes on "The Mathematics
  1115.     of Computer Graphics."  That technique works for any quadric surface
  1116.     (cylinders aren't bounded, though) under any homogeneous transform
  1117.     (including perspective!)  He also talks about how to render these
  1118.     things using his method.  I tried it; it works great and is 
  1119.     incredibly fast.  I didn't implement many of his optimizations and
  1120.     can draw a texture mapped cylinder (no end caps) that fills the
  1121.     screen (512x512) on a VAX 780 in under a minute.
  1122.  
  1123.     As to how this applies to ray tracing, he gives a method for
  1124.     finding the silhouette of a quadric as well as minima and maxima.
  1125.     It allows for easy use of forward differencing, so should be fast
  1126.     enough to "render" quadrics into an octree.
  1127.  
  1128.     Bob Conley did a volume-oriented ray tracer for his thesis.
  1129.     I don't remember the details, but there'll be a long note about
  1130.     it that I'll pass on.  He mentions that his code can do index
  1131.     of refraction varying over position.  He uses a grid technique
  1132.     similar to Fujimoto's.   
  1133.  
  1134. ---------------------------------------------------------------
  1135.  
  1136. From Jim Arvo:
  1137.  
  1138.     Just when you thought we had moved from octrees on to other things...
  1139. This just occurred to me yesterday. (Actually, that was several days ago.
  1140. This mail got bounced back to me twice now.  More e-mail gremlins I guess.)
  1141.  
  1142.  
  1143. LINEAR-TIME VOXEL WALKING FOR OCTREES
  1144. -------------------------------------
  1145.  
  1146. Here is a new way to attack the problem of "voxel walking" in octrees (at 
  1147. least I think it's new).  By voxel walking I mean identifying the successive
  1148. voxels along the path of a ray.  This is more for theoretical interest than
  1149. anything else, though the algorithm described below may actually be 
  1150. practical in some situations.  I make no claims about the practicality, 
  1151. however, and stick to theoretical time complexity for the most part.
  1152.  
  1153. For this discussion assume that we have recursively subdivided a cubical
  1154. volume of space into a collection of equal-sized voxels using a BSP tree
  1155.  -- i.e. each level imposes a single axis-orthogonal partitioning plane.  
  1156. The algorithm is much easier to describe using BSP trees, and from the point
  1157. of view of computational complexity, there is basically no difference 
  1158. between BSP trees and octrees.  Also, assuming that the subdivision has been
  1159. carried out to uniform depth throughout simplifies the discussion, but is by
  1160. no means a prerequisite.  This would defeat the whole purpose because we all
  1161. know how to efficiently walk the voxels along a ray in the context of 
  1162. uniform subdivision -- i.e. use a 3DDDA.
  1163.  
  1164. Assuming that the leaf nodes form an NxNxN array of voxels, any given ray 
  1165. will pierce at most O(N) voxels.  The actual bound is something like 3N,
  1166. but the point is that it's linear in N.  Now, suppose that we use a 
  1167. "re-traversal" technique to move from one voxel to the next along the ray.
  1168. That is, we create a point that is guaranteed to lie within the next voxel
  1169. and then traverse the hierarchy from the root node until we find the leaf
  1170. node, or voxel, containing this point.  This requires O( log N ) operations.
  1171. In real life this is quite insignificant, but here we are talking about the
  1172. actual time complexity.  Therefore, in the worst case situation of following
  1173. a ray through O( N ) voxels, the "re-traversal" scheme requires O( N log N )
  1174. operations just to do the "voxel walking."  Assuming that there is an upper
  1175. bound on the number of objects in any voxel (i.e. independent of N), this 
  1176. is also the worst case time complexity for intersecting a ray with the
  1177. environment.
  1178.  
  1179. In this note I propose a new "voxel walking" algorithm for octrees (call it
  1180. the "partitioning" algorithm for now) which has a worst case time complexity
  1181. of O( N ) under the conditions outlined above.  In the best case of finding
  1182. a hit "right away" (after O(1) voxels), both "re-traversal" and 
  1183. "partitioning" have a time complexity of O( log N ).  That is:
  1184.  
  1185.                     BEST CASE: O(1) voxels    WORST CASE: O(N) voxels
  1186.                     searched before a hit.    searched before a hit.
  1187.                   +---------------------------------------------------+
  1188.                   |                                                   |
  1189.   Re-traveral     |     O( log N )               O( N Log N )         |
  1190.                   |                                                   |
  1191.   Partitioning    |     O( log N )               O( N )               |
  1192.                   |                                                   |
  1193.                   +---------------------------------------------------+
  1194.  
  1195. The new algorithm proceeds by recursively partitioning the ray into little
  1196. line segments which intersect the leaf voxels.  The top-down nature of the 
  1197. recursive search ensures that partition nodes are only considered ONCE PER 
  1198. RAY.  In addition, the voxels will be visited in the correct order, thereby 
  1199. retaining the O( log N ) best case behavior.
  1200.  
  1201. Below is a pseudo code description of the "partitioning" algorithm.  It is
  1202. the routine for intersecting a ray with an environment which has been 
  1203. subdivided using a BSP tree.  Little things like checking to make sure
  1204. the intersection is within the appropriate interval have been omitted.
  1205. The input arguments to this routine are:
  1206.  
  1207.     Node : A BSP tree node which comes in two flavors -- a partition node 
  1208.            or a leaf node.  A partition node defines a plane and points to
  1209.            two child nodes which further partition the "positive" and 
  1210.            "negative" half-spaces.  A leaf node points to a list of 
  1211.            candidate objects.
  1212.  
  1213.     P    : The ray origin.  Actually, think of this as an endpoint of a 3D 
  1214.            line segment, since we are constraining the "ray" to be of finite
  1215.            length.
  1216.  
  1217.     D    : A unit vector indicating the ray direction.
  1218.  
  1219.     len  : The length of the "ray" -- or, more appropriately, the line 
  1220.            segment.  This is measured from the origin, P, along the 
  1221.            direction vector, D.
  1222.  
  1223. The function "Intersect" is initially passed the root node of the BSP tree,
  1224. the origin and direction of the ray, and a length, "len", indicating the 
  1225. maximum distance to intersections which are to be considered.  This starts
  1226. out being the distance to the far end of the original bounding cube.
  1227.  
  1228. ============================================================================
  1229.  
  1230. FUNCTION Intersect( Node, P, D, len ) RETURNING "results of intersection"
  1231.  
  1232.     IF Node is NIL THEN RETURN( "no intersection" )
  1233.  
  1234.     IF Node is a leaf THEN BEGIN
  1235.  
  1236.         intersect ray (P,D) with objects in the candidate list
  1237.  
  1238.         RETURN( "the closest resulting intersection" )
  1239.  
  1240.         END IF
  1241.  
  1242.     dist := signed distance along ray (P,D) to plane defined by Node
  1243.  
  1244.     near := child of Node in half-space which contains P
  1245.  
  1246.     IF 0 < dist < len THEN BEGIN  /* the interval intersects the plane */
  1247.  
  1248.         hit_data := Intersect( near, P, D, dist )
  1249.  
  1250.         IF hit_data <> "no intersection" THEN RETURN( hit_data )
  1251.  
  1252.         Q := P + dist * D   /* 3D coords of point of intersection */
  1253.  
  1254.         far := child of Node in half-space which does NOT contain P
  1255.  
  1256.         RETURN( Intersect( far, Q, D, len - dist ) )
  1257.  
  1258.         END IF
  1259.  
  1260.     ELSE RETURN( Intersect( near, P, D, len ) ) 
  1261.  
  1262.     END
  1263.  
  1264. ============================================================================
  1265.  
  1266. As the BSP tree is traversed, the line segments are chopped up by the
  1267. partitioning nodes.  The "shrinking" of the line segments is critical to 
  1268. ensure that only relevent branches of the tree will be traversed.
  1269.  
  1270. The actual encodings of the intersection data, the partitioning planes, and
  1271. the nodes of the tree are all irrelevant to this discussion.  These are 
  1272. "constant time" details.  Granted, they become exceedingly important when
  1273. considering whether the algorithm is really practial.  Let's save this
  1274. for later.
  1275.  
  1276. A naive (and incorrect) proof of the claim that the time complexity of this
  1277. algorithm is O(N) would go something like this:
  1278.  
  1279.     The voxel walking that we perform on behalf of a single ray is really
  1280.     just a search of a binary tree with voxels at the leaves.  Since each 
  1281.     node is only processed once, and since a binary tree with k leaves has
  1282.     k - 1 internal nodes, the total number of nodes which are processed in 
  1283.     the entire operation must be of the same order as the number of leaves.
  1284.     We know that there are O( N ) leaves.  Therefore, the time complexity 
  1285.     is O( N ).
  1286.  
  1287. But wait!  The tree that we search is not truly binary since many of the 
  1288. internal nodes have one NIL branch.  This happens when we discover that the 
  1289. entire current line segment is on one side of a partitioning plane and we
  1290. prune off the branch on the other side.  This is essential because there
  1291. are really N**3 leaves and we need to discard branches leading to all but 
  1292. O( N ) of them.  Thus, k leaves does not imply that there are only k - 1 
  1293. internal nodes.  The quention is, "Can there be more than O( k ) internal 
  1294. nodes?".
  1295.  
  1296. Suppose we were to pick N random voxels from the N**3 possible choices, then 
  1297. walk up the BSP tree marking all the nodes in the tree which eventually lead
  1298. to these N leaves.  Let's call this the subtree "generated" by the original
  1299. N voxels.  Clearly this is a tree and it's uniquely determined by the leaves.
  1300. A very simple argument shows that the generated subtree can have as many as 
  1301. 2 * ( N - 1 ) * log N nodes.  This puts us right back where we started from,
  1302. with a time complexity of O( N log N ), even if we visit these nodes only 
  1303. once.  This makes sense, because the "re-traversal" method, which is also 
  1304. O( N log N ), treats the nodes as though they were unrelated.  That is, it 
  1305. does not take advantage of the fact that paths leading to neighboring 
  1306. voxels are likely to be almost identical, diverging only very near the 
  1307. leaves.  Therefore, if the "partitioning" scheme really does visit only 
  1308. O( N ) nodes, it does so because the voxels along a ray are far from random.
  1309. It must implicitly take advantage of the fact that the voxels are much more
  1310. likely to be brothers than distant cousins.
  1311.  
  1312. This is in fact the case.  To prove it I found that all I needed to assume 
  1313. about the voxels was connectedness -- provided I made some assumptions
  1314. about the "niceness" of the BSP tree.  To give a careful proof of this is
  1315. very tedious, so I'll just outline the strategy (which I *think* is 
  1316. correct).  But first let's define a couple of convenient terms:
  1317.  
  1318. 1)  Two voxels are "connected" (actually "26-connected") if they meet at a 
  1319.     face, an edge, or a corner.  We will say that a collection of voxels is
  1320.     connected if there is a path of connected voxels between any two of them.
  1321.  
  1322. 2)  A "regular" BSP tree is one in which each axis-orthogonal partition 
  1323.     divides the parent volume in half, and the partitions cycle: X, Y, Z, X,
  1324.     Y, Z, etc. (Actually, we can weaken both of these requirements 
  1325.     considerably and still make the proof work.  If we're dealing with 
  1326.     "standard" octrees, the regularity is automatic.)
  1327.  
  1328. Here is a sequence of little theorems which leads to the main result:
  1329.  
  1330.     THEOREM 1:  A ray pierces O(N) voxels.
  1331.  
  1332.     THEOREM 2:  The voxels pierced by a ray form a connected set.
  1333.  
  1334.     THEOREM 3:  Given a collection of voxels defined by a "regular" BSP 
  1335.                 tree, any connected subset of K voxels generates a unique 
  1336.                 subtree with O( K ) nodes.
  1337.  
  1338.     THEOREM 4:  The "partitioning" algorithm visits exactly the nodes of 
  1339.                 the subtree generated by the voxels pierced by a ray.  
  1340.                 Furthermore, each of these nodes is visited exaclty once 
  1341.                 per ray.
  1342.  
  1343.     THEOREM 5:  The "partitioning" algorithm has a worst case complexity 
  1344.                 of O( N ) for walking the voxels pierced by a ray.
  1345.  
  1346. Theorems 1 and 2 are trivial.  With the exception of the "uniqueness" part, 
  1347. theorem 3 is a little tricky to prove.  I found that if I completely removed
  1348. either of the "regularity" properties of the BSP tree (as opposed to just
  1349. weakening them), I could construct a counterexample.  I think that 
  1350. theorem 3 is true as stated, but I don't like my "proof" yet.  I'm looking 
  1351. for an easy and intuitive proof.  Theorem 4 is not hard to prove at all.  
  1352. All the facts become fairly clear if you see what the algorithm is doing.  
  1353. Finally, theorem 5, the main result, follows immediately from theorems 1 
  1354. through 4.
  1355.  
  1356.  
  1357. SOME PRACTICAL MATTERS:
  1358.  
  1359. Since log N is typically going to be very small -- bounded by 10, say -- 
  1360. this whole discussion may be purely academic.  However, just for the heck 
  1361. of it, I'll mention some things which could make this a (maybe) 
  1362. competative algorithm for real-life situations (in as much as ray tracing 
  1363. can ever be considered to be "real life").
  1364.  
  1365. First of all, it would probably be advisable to avoid recursive procedure
  1366. calls in the "inner loop" of a voxel walker.  This means maintaining an 
  1367. explicit stack.  At the very least one should "longjump" out of the 
  1368. recursion once an intersection is found.
  1369.  
  1370. The calculation of "dist" is very simple for axis-orthogonal planes, 
  1371. consisting of a subtract and a multiply (assuming that the reciprocals of 
  1372. the direction components are computed once up front, before the recursion 
  1373. begins).
  1374.  
  1375. A nice thing which falls out for free is that arbitrary partitioning 
  1376. planes can be used if desired.  The only penalty is a more costly distance
  1377. calculation.  The rest of the algorithm works without modification.  There 
  1378. may be some situations in which this extra cost is justified.
  1379.  
  1380. Sigh.  This turned out to be much longer than I had planned...
  1381.  
  1382. >>>>>> A followup message:
  1383.  
  1384. Here is a slightly improved version of the algorithm in my previous mail.
  1385. It turns out that you never need to explicitly compute the points of 
  1386. intersection with the partitioning planes.  This makes it a little more
  1387. attractive. 
  1388.  
  1389.                                                                  -- Jim
  1390.  
  1391.  
  1392. FUNCTION BSP_Intersect( Ray, Node, min, max ) RETURNING "intersection results"
  1393.  
  1394. BEGIN
  1395.  
  1396.     IF Node is NIL THEN RETURN( "no intersection" )
  1397.  
  1398.     IF Node is a leaf THEN BEGIN  /* Do the real intersection checking */
  1399.  
  1400.         intersect Ray with each object in the candidate 
  1401.         list discarding those farther away than "max." 
  1402.  
  1403.         RETURN( "the closest resulting intersection" )
  1404.  
  1405.         END IF
  1406.  
  1407.     dist := signed distance along Ray to plane defined by Node
  1408.  
  1409.     near := child of Node for half-space containing the origin of Ray
  1410.  
  1411.     far  := the "other" child of Node -- i.e. not equal to near.
  1412.  
  1413.     IF dist > max OR dist < 0 THEN  /* Whole interval is on near side. */
  1414.  
  1415.         RETURN( BSP_Intersect( Ray, near, min, max ) )
  1416.  
  1417.     ELSE IF dist < min THEN  /* Whole interval is on far side. */
  1418.  
  1419.         RETURN( BSP_Intersect( Ray, far , min, max ) )
  1420.  
  1421.     ELSE BEGIN  /* the interval intersects the plane */
  1422.  
  1423.         hit_data := BSP_Intersect( Ray, near, min, dist ) /* Test near side */
  1424.  
  1425.         IF hit_data indicates that there was a hit THEN RETURN( hit_data )
  1426.  
  1427.         RETURN( BSP_Intersect( Ray, far, dist, max ) )  /* Test far side. */
  1428.  
  1429.         END IF
  1430.  
  1431.     END
  1432.  
  1433.  
  1434. ------------------------------------------------------------------------
  1435.  
  1436. Some people turn out to be on the e-mail mailing list but not the hardcopy
  1437. list for the RT News.  In case you don't get the RT News in hardcopy form, I'm
  1438. including the Efficiency Tricks article & the puzzle from it in this issue.
  1439.  
  1440.  
  1441. Efficiency Tricks, by Eric Haines
  1442. ---------------------------------
  1443.  
  1444. Given a ray-tracer which has some basic efficiency scheme in use, how can we
  1445. make it faster?  Some of my tricks are below - what are yours?
  1446.  
  1447. [HBV stands for Hierarchical Bounding Volumes]
  1448.  
  1449. Speed-up #1:  [HBV and probably Octree] Keep track of the closest intersection
  1450. distance.  Whenever a primitive (i.e. something that exists - not a bounding
  1451. volume) is hit, keep its distance as the maximum distance to search.  During
  1452. further intersection testing use this distance to cut short the intersection
  1453. calculations.
  1454.  
  1455. Speed-up #2:  [HBV and possibly Octree] When building the ray tree, keep the
  1456. ray-tree around which was previously built.  For each ray-tree node, intersect
  1457. the object in the old ray tree, then proceed to intersect the new ray tree.
  1458. By intersecting the old object first you can usually obtain a maximum distance
  1459. immediately, which can then be used to aid Speed-up #1.
  1460.  
  1461. Speed-up #3:  When shadow testing, keep the opaque object (if any) which
  1462. shadowed each light for each ray-tree node.  Try these objects immediately
  1463. during the next shadow testing at that ray-tree node.  Odds are that whatever
  1464. shadowed your last intersection point will shadow again.  If the object is hit
  1465. you can immediately stop testing because the light is not seen.
  1466.  
  1467. Speed-up #4:  When shadow testing, save transparent objects for later
  1468. intersection.  Only if no opaque object is hit should the transparent objects
  1469. be tested.
  1470.  
  1471. Speed-up #5:  Don't calculate the normal for each intersection.  Get the
  1472. normal only after all intersection calculations are done and the closest object
  1473. for each node is know: after all, each ray can have only one intersection point
  1474. and one normal.  (Saving intermediate results is recommended for some
  1475. intersection calculations.)
  1476.  
  1477. Speed-up #6:  [HBV only] When shooting rays from a surface (e.g. reflection,
  1478. refraction, or shadow rays), get the initial list of objects to intersect
  1479. from the bounding volume hierarchy.  For example, a ray beginning on a sphere
  1480. must hit the sphere's bounding volume, so include all other objects in this
  1481. bounding volume in the immediate test list.  The bounding volume which
  1482. is the father of the sphere's bounding volume must also automatically be hit,
  1483. and its other sons should automatically be added to the test list, and so on
  1484. up the object tree.  Note also that this list can be calculated once for any
  1485. object, and so could be created and kept around under a least-recently-used
  1486. storage scheme.
  1487.  
  1488. ------------------------------------------
  1489.  
  1490. A Rendering Trick and a Puzzle, by Eric Haines
  1491. ----------------------------------------------
  1492.  
  1493. One common trick is to put a light at the eye to do better ambient lighting.
  1494. Normally if a surface is lit by only ambient light, its shading is pretty
  1495. crummy.  For example, a non-reflective cube totally in shadow will have all of
  1496. its faces shaded the exact same shade - very unrealistic.  The light at the eye
  1497. gives the cube definition.  Note that a light at the eye does not need shadow
  1498. testing - wherever the eye can see, the light can see, and vice versa.
  1499.  
  1500. The puzzle:  Actually, I lied.  This technique can cause a subtle error.  Do you
  1501. know what shading error the above technique would cause? [hint: assume the Hall
  1502. model is used for shading].
  1503.  
  1504. ---------------------------------------------------------------------------
  1505.  
  1506. USENET roundup:
  1507.  
  1508. Other than a hilarious set of messages begun when Paul Heckbert's Jell-O (TM)
  1509. article was posted to USENET, and the perennial question "How do I find if a
  1510. point is inside a polygon?", not much of interest.  However, I did get a copy
  1511. of the errata in _Procedural Elements for Computer Graphics_ from David Rogers.
  1512.  
  1513. I updated my edition (the Second) with these corrections, which was generally
  1514. a time drain: my advice is to keep the errata sheets in this edition, checking
  1515. them only if you are planning to use an algorithm.  However, the third edition
  1516. corrections are mercifully short.
  1517.  
  1518.  
  1519. From: "David F. Rogers" <rochester!harvard!USNA.MIL!dfr@cornell.UUCP>
  1520. From:     David F. Rogers  <dfr@USNA.MIL>
  1521. Subject:  PECG correction
  1522. Date:     Thu, 10 Mar 88 13:21:11 EST
  1523.  
  1524. Correction list for PECG  2/26/86
  1525. David F. Rogers
  1526.  
  1527. There have been 3 printings of this book to date.
  1528. The 3rd printing occurred in approximately March 85.
  1529.  
  1530. To see if you have the 3rd printing look on page 386,
  1531. 3rd line down and see if the word magenta is spelled
  1532. correctly.  If it is, you have the 3rd printing. If not, then
  1533. you have the 2nd or 1st printing.
  1534.  
  1535. To see if you have the 2nd printing look on page 90.  If
  1536. the 15th printed line in the algorithm is
  1537.  
  1538.   while Pixel(x,y) <> Boundary value
  1539.  
  1540. you have the 2nd printing.  If not you have the 1st printing.
  1541.  
  1542. Please send any additional corrections to me at
  1543.  
  1544. Professor David F. Rogers
  1545. Aerospace Engineering Department
  1546. United States Naval Academy
  1547. Annapolis, Maryland 21402
  1548.  
  1549. uucp:decvax!brl-bmd!usna!dfr
  1550. arpa:dfr@usna
  1551. _____________________________________________________________
  1552.  
  1553. Known corrections to the third printing:
  1554.  
  1555. Page    Para./Eq.    Line    Was        Should be
  1556.  
  1557. 72    2        11    (5,5)        (5,1)
  1558. 82    1 example    4    (8,5)        delete
  1559. 100    5th equation        upper limit on integral should be 2
  1560.                 vice 1
  1561. 143    Fig. 3-14        yes branch of t < 0 and t > 1 decision blocks
  1562.                 should extend down to Exit-line invisible
  1563. 144    Cyrus-Beck
  1564.     algorithm    7    then 3        then 4
  1565.             11    then 3        then 4
  1566.  
  1567. 145    Table 3-7    1    value for w
  1568.                 [2 1]        [-2 1]
  1569.  
  1570. 147    1st eq.     23    V sub e sub x j V sub e sub y j
  1571. ______________________________________________________________
  1572.  
  1573. Known corrections to the second printing:  (above plus)
  1574.  
  1575. text:
  1576.  
  1577. 19    2        5    Britian     Britain
  1578. 36    Eq. 3        10    replace 2nd + with =
  1579. 47    4        6    delta' > 0      delta'< = 0
  1580. 82    1        6    set        complement
  1581. 99    1        6    multipled    multiplied
  1582. 100    1        6    Fig. 2-50a    Fig. 2-57a
  1583. 100    1        8    Fig. 2-50b    Fig. 2-57b
  1584. 122    write for new page
  1585. 186    2        6    Fig. 3-37a    Fig. 3-38a
  1586. 186    2        9    Fig. 3-38    Fig. 3-38b
  1587. 187    Ref. 3-5        to appear    Vol. 3, pp. 1-23, 1984
  1588. 194    Eq. 1            xn +        xn -
  1589. 224    14 lines from bottom    t = 1/4     t = 3/4
  1590. 329    last eq.        -0.04        -0.13
  1591.     next to last eq.    -0.04 twice    -0.13 twice
  1592.     3rd from bottom     0.14        -0.14
  1593. 330    1st eq.         -0.09        -0.14
  1594.     2nd eq.         -0.09        -0.14
  1595.     3rd eq.         -0.17        -0.27
  1596.     4th eq.         0.36        0.30
  1597.                 5.25        4.65
  1598.     last eq.        5.25        4.65
  1599. 332            4    beta <        beta >
  1600.             6    beta <        beta >
  1601. 355    2nd eq.         w = s(u,w)    w = s(theta,phi)
  1602. 385    2        5    magneta     magenta
  1603. 386            3    magneta     magenta
  1604.  
  1605. algorithms: (send self-addressed long stamped envelope for xeroxed
  1606.          corrections)
  1607.  
  1608. 97    Bresenham    1    insert words  first quadrant  after modified
  1609.             10    remove ()
  1610.             12    1/2        I/2
  1611.             14    delta x     x sub 2
  1612.  
  1613. 117    Explicit    18    Icount = 0    delete
  1614.     clipping
  1615.             18    insert        m = Large
  1616. 120            9    P'2             P'1
  1617.             12    insert after    Icount = 0
  1618.                 end if
  1619.             13    insert after    1 if Icount <> 0 then
  1620.                 neither end       P' = P0
  1621.             14            removed statement label 1
  1622.             15    >=        >
  1623.             17            delete
  1624.             18            delete
  1625.             43    y>        yT>
  1626.  
  1627. 122-124 Sutherland-    write for new pages
  1628.     Cohen
  1629.  
  1630. 128    midpoint    4    insert after    initialize i
  1631.                         i = 1
  1632. 129            6    i = 1        delete
  1633.             6    insert        save original p1
  1634.                         Temp = P1
  1635.             8    i = 2        i > 2
  1636.             11,12    save original.. delete
  1637.                 Temp = P1
  1638.             14    add statement label 2
  1639. 130            19-22    delete
  1640.             24    i = 2        i = i + 1
  1641.             29    <>        <> 0
  1642.             33    P1        P
  1643.  
  1644. 143            3    wdotn        Wdotn
  1645. 144            20    >=        >
  1646.  
  1647. 176    Sutherland-    1    then 5        then 4
  1648.     Hodgman
  1649. 177            9    4 x 4        2 x 2
  1650.  
  1651. 198    floating    21,22    x,y        Xprev,Yprev
  1652.     horizon
  1653. 199            4    Lower        Upper
  1654. 200            11-19    rewrite as
  1655.                 if y < Upper(x) and y > Lower(x) then Cflag = 0
  1656.                 if y> = Upper(x) then Cflag = 1
  1657.                 if y< = Lower(x) then Cflag = -1
  1658.             29    delete
  1659.             31    Xinc        (x2-x1)
  1660.             36    step Xinc    step 1
  1661. 201            4    delete
  1662.             6    Xinc = 0       (x2-x1) = 0
  1663.             12    Y1 -        Y1 + Slope -
  1664.             12    insert after    Csign = Ysign
  1665.             13    Yi = Y1     Yi = Y1 + Slope
  1666.             13    insert after    Xi = X1 + 1
  1667.             14-end    rewrite as    while(Csign = Ysign)
  1668.                            Yi = Yi + Slope
  1669.                             Xi = Xi + 1
  1670.                             Csign = Sign(Yi - Array(Xi))
  1671.                         end while
  1672.                         select nearest integer value
  1673.                         if |Yi -Slope -Array(Xi - 1)| <=
  1674.                           |Yi - Array(Xi)| then
  1675.                             Yi = Yi - Slope
  1676.                             Xi = Xi -1
  1677.                         end if
  1678.                          end if
  1679.                      return
  1680.  
  1681. 258    subroutine Compute    N        i
  1682.  
  1683. 402    HSV to Rgb    12    insert after    end if
  1684.             25    end if        delete
  1685.  
  1686. 404    HLS to RGB    2    M1 = L*(1 - S)    M2 = L*(1 + S)
  1687.             4    M1        M2
  1688.             6    M2 = 2*L - M1    M1 = 2*L - M2
  1689.             10-12    =1        =L
  1690.             18    H        H + 120
  1691.             19    Value + 120    Value
  1692.             22    H        H - 120
  1693.             23    Value - 120    Value
  1694.  
  1695. 405    RGB to HLS    22    M1 + M2     M1 - M2
  1696.  
  1697. figures:
  1698.  
  1699. 77    Fig. 2-39a        interchange Edge labels for scanlines 5 & 6
  1700.     Fig. 2-39b        interchange information for lists 1 & 3, 2 & 4
  1701.  
  1702. 96    Fig. 2-57a,b        y sub i + 1    y sub(i+1)
  1703.  
  1704. 99    Fig. 2-59        abcissa of lowest plot should be xi vice x
  1705.  
  1706. 118    Fig. 3-4        first initialization block - add m = Large
  1707.                 add F entry point just above IFLAG = -1
  1708.                 decision block
  1709. 119                to both IFLAG=-1 blocks add exit points to F
  1710.  
  1711. 125    Fig. 3-5        line f - interchange Pm1 & Pm2
  1712.  
  1713. 128    Fig. 3-6a        add initialization block immediately after Start
  1714.                 initialize i, i=1
  1715.  
  1716.                 immediately below new initialization block add
  1717.                 entry point C
  1718.  
  1719.                 in Look for the farthest vissible point from P1
  1720.                 block - delete i=1
  1721.  
  1722.                 in decision block i = 2 - change to i > 2
  1723.  
  1724. 129    Fig. 3-6b        move return to below Save P1 , T = P1 block
  1725.  
  1726.                 remove Switch end point codes block
  1727.  
  1728.                 in Reset counter block replace i=2 with i=i + 1
  1729.  
  1730. 180    Fig. 3-34b        Reverse direction of arrows of box surrounding
  1731.                 word Start.
  1732.  
  1733. 330    Fig. 5-16a        add P where rays meet surface
  1734.  
  1735. 374    Fig. 5-42        delete unlabelled third exit from decision
  1736.                 box r ray?
  1737.  
  1738. 377    Fig. 5-44        in lowest box I=I+I sub(l (sub j)) replace
  1739.                 S with S sub(j)
  1740. _________________________________________________________________________
  1741.  
  1742. Known corrections to the first printing:
  1743.  
  1744. 90,91    scan line seed        write for xeroxed corrections
  1745.     fill algorithm
  1746. ________________________________________________________________________
  1747. END OF RTNEWS
  1748.